package com.boot.springBoot.util.threadPool;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.apache.poi.ss.formula.functions.T;

import lombok.extern.slf4j.Slf4j;

/**
 * 自己动手手写一个线程池工具类   基于CPU的核数
 */
@Slf4j
public class ThreadPoolUtil {
	
	/**
     * 根据cpu的数量动态的配置核心线程数和最大线程数
     */
	private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors(); 
	
	/**
	 * 核心线程数 = CPU核心数 + 1
	 */
	private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
	
	
	/**
	 * 线程池最大线程数 = CPU核心数 * 2 + 1
	 */
	private  static final int MAX_POOL_SIZE = CPU_COUNT * 2 + 1;
	
	/**
    * 非核心线程闲置时超时2s
    */
   private static final int KEEP_ALIVE = 2;
   
   /**
    * 线程池对象
    */
   private ThreadPoolExecutor threadPool;
   
   /**
    * 通过单例获取实例 避免产生过多对象消费资源，所以采用单例模式
    */
	private ThreadPoolUtil() {
		// TODO Auto-generated constructor stub
	}
	
	private static ThreadPoolUtil instance;
	
	public synchronized static ThreadPoolUtil getInstance() {
		if(null == instance) {
			instance = new ThreadPoolUtil();
		}
		return instance;
	}
	
	/**
	 * 
	    * @Title: execute  
	    * @Description: TODO(开启一个无返回结果的线程)  
	    * @param @param r    参数  
	    * @return void    返回类型  
	    * @throws
	 */
	public void execute(Runnable r) {
		
		if(null == threadPool) {
			threadPool = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS,
					new ArrayBlockingQueue<Runnable>(20),Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
		}
		
		threadPool.execute(r);
	}
	
	/**
	 * 
	    * @Title: submit  
	    * @Description: TODO(开启一个有返回结果的线程)  
	    * @param @param r
	    * @param @return    参数  
	    * @return Future<T>    返回类型  
	    * @throws
	 */
	public Future<T> submit(Callable<T> c) {
		
		if(null == threadPool) {
			threadPool = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE,
					TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(20), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
		}
		
		return threadPool.submit(c);
	}
	
	/**
	 * 
	    * @Title: cancel  
	    * @Description: TODO(把任务移除等待队列)  
	    * @param @param r    参数  
	    * @return void    返回类型  
	    * @throws
	 */
	public void cancel(Runnable r) {
		if(r != null) {
			threadPool.getQueue().remove(r);
		}

	}
	
	public static void main(String[] args) {
		System.out.println(Runtime.getRuntime().availableProcessors());
	}
}
